﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Collections.Specialized;
using System.Text;
using SCRUM.Core.BusinessObjects;
using SCRUM.Core.DAO;
using SCRUM.Core.MembershipProviders;
using System.Web.UI.WebControls;

/// <summary>
/// HierarchicalObjectDetails displays information about some Item in form of unified form.
/// Enables user to:
///  * display selected Item
///  * update eddited selected Item in persistent storage
///  * create new Item in persistent storage
///  * delete selected Item from persistent storage
/// </summary>
public abstract class ObjectDetails<Item> : UserControl
{
    public event EventHandler ItemChangedEvent;

    /// <summary>
    /// Gets or sets the item on which operates these Details
    /// </summary>
    /// <value>The sprint.</value>
    public virtual Item SelectedItem
    {
        get
        {
            return selectedItem;
        }
        set
        {
            selectedItem = value;
            //if(AvailableSuperiorItems == null) LoadAvailableSuperiorItems();
            DisplayItem(value);
            //SetChildControlsReadOnlyMode(this.ReadOnly);
        }
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        SetChildControlsReadOnlyMode(this.ReadOnly);
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="HierarchicalObjectDetails"/> is editable.
    /// </summary>
    /// <value><c>true</c> if editable; otherwise, <c>false</c>.</value>
    public bool ReadOnly
    {
        get
        {
            return this.readOnly;
        }
        set
        {
            //SetChildControlsReadOnlyMode(value);
            this.readOnly = value;
        }
    }

    private void SetChildControlsReadOnlyMode(bool value)
    {
        foreach (Control control in this.panelWithControls.Controls)
        {
            if (control is WebControl)
            {
                (control as WebControl).Enabled = !value;
            }
            if (control is ScrumWebControl)
            {
                (control as ScrumWebControl).ReadOnly = value;
            }
        }
    }

    /// <summary>
    /// Are these details editable?
    /// </summary>
    private bool readOnly;

    /// <summary>
    /// Gets or sets the validation group for details (form)
    /// </summary>
    /// <value>The validation group.</value>
    public string ValidationGroup
    {
        get { return this.validationGroup; }
        set
        {
            this.validationGroup = value;
            SetInputsValidationGroup(value);
        }
    }

    /// <summary>
    /// Displays all fields of the selected item into textboxes in form.
    /// </summary>
    public abstract void DisplayItem(Item item);

    /// <summary>
    /// Updates changed item in persistent storage.
    /// </summary>
    /// <returns>edited item</returns>
    public abstract Item EditItem(int ID);

    /// <summary>
    /// Creates the item in persistent storage).
    /// </summary>
    /// <returns>creted item</returns>
    public abstract Item CreateItem();

    /// <summary>
    /// Deletes the item from persistent storage.
    /// </summary>
    public abstract void DeleteItem(Item item);

    /// <summary>
    /// Validates user's input in detail form.
    /// </summary>
    /// <returns></returns>
    public abstract bool ValidateInput();

    /// <summary>
    /// Selected Item
    /// </summary>
    protected Item selectedItem;

    /// <summary>
    /// Validation group where control belongs
    /// </summary>
    private string validationGroup;

    /// <summary>
    /// List of all inputs with which creates this HierarchicalObjectDetails. All descendants loads this list in constructor
    /// </summary>
    private IList<ScrumInput> inputs_;

    /// <summary>
    /// Sets the ValidationGroup to all inputs in form.
    /// </summary>
    /// <param name="validationGroup">The validation group.</param>
    private void SetInputsValidationGroup(string validationGroup)
    {
        //if (inputs.Count == 0) this.LoadExtendedInputs();
        foreach (ScrumInput input in inputs)
        {
            input.ValidationGroup = validationGroup;
        }
    }

    /// <summary>
    /// Gets or sets the List of all inputs with which creates this HierarchicalObjectDetails. All descendants loads this list in constructor
    /// </summary>
    /// <value>The inputs.</value>
    protected IList<ScrumInput> inputs
    {
        get
        {
            if (inputs_ == null) inputs_ = this.LoadExtendedInputs();
            return inputs_;
        }
        set
        {
            inputs_ = value;
        }
    }

    /// <summary>
    /// Loads the extended inputs.
    /// </summary>
    /// <returns></returns>
    protected abstract IList<ScrumInput> LoadExtendedInputs();

    /// <summary>
    /// Clears all textboxes in form to ""
    /// </summary>
    protected void ClearTextBoxes()
    {
        foreach (ScrumInput input in this.inputs)
        {
            input.Text = "";
        }
    }

    /// <summary>
    /// Loads all the extended inputs from panel into protected inputs list
    /// </summary>
    /// <param name="panel">The panel.</param>
    protected IList<ScrumInput> LoadExtendedInputsFrom(Panel panel)
    {
        IList<ScrumInput> ret = new List<ScrumInput>();
        foreach (var item in panel.Controls)
	    {
    	    if(item is ScrumInput)
                ret.Add(item as ScrumInput);
	    }
        return ret;
    }

    protected IList<ScrumWebControl> LoadScrumWebControls(Panel panel)
    {
        IList<ScrumWebControl> ret = new List<ScrumWebControl>();
        foreach (var item in panel.Controls)
        {
            if (item is ScrumWebControl)
                ret.Add(item as ScrumWebControl);
        }
        return ret;
    }

    protected IList<ScrumWebControl> scrumWebControls
    {
        get
        {
            if (_webControls == null)
            {
                _webControls = LoadScrumWebControls(this.panelWithControls);
            }
            return _webControls;
        }
    }
    private IList<ScrumWebControl> _webControls = null;

    protected abstract Panel panelWithControls { get; }

}

